﻿using org.xisoft.game.utils;
using org.xisoft.game.utils.game;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ReversiModule.Chess.Algorithms
{
    class MulThreadAlgorithm<AI>: AiAlgorithm
        where AI: AiAlgorithm,new()
    {
        public override MoveAction Search(ReversiBoard gobangBroad, int depth)
        {
            List<MoveAction> list = GetAllCanMoves(gobangBroad);
            MoveAction bestMove = null;
            using (ThreadExecuter threadExecuter = new ThreadExecuter())
            {
                Action<MoveAction> searchAction = moveAction =>
                {
                    lock (this)
                    {
                        if (bestMove == null || bestMove.Score < moveAction.Score)
                            bestMove = moveAction;
                    }
                };

                foreach (MoveAction moveAction in list)
                {
                    ReversiBoard broad = gobangBroad.Clone() as ReversiBoard;
                    broad.DoNextMove(moveAction);
                    SearchTask task = new SearchTask { moveAction = moveAction, aiChessboard = broad, callback = searchAction };
                    threadExecuter.Execute(task.Run);
                    //task.Run();
                }

                threadExecuter.WaitAllFinish();
            }
            return bestMove;
        }

        class SearchTask
        {
            public MoveAction moveAction;
            public ReversiBoard aiChessboard;
            public Action<MoveAction> callback;

            public void Run()
            {
                AI ai = new AI();
                MoveAction action = ai.Search(aiChessboard, ai.MaxDeep - 1);
                if (action != null)
                    moveAction.Score -= action.Score;


                callback(moveAction);
            }
        }
    }
}
